<template>
  <div class="editor-container" :style="{ height: editorHeight }">
    <!-- Quill编辑器容器 -->
    <div ref="editorEl"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from 'vue'
import Quill from 'quill'
import 'quill/dist/quill.snow.css'
import DOMPurify from 'dompurify'
import service from '@/utils/request'
import Emoji from '@/components/Emoji.vue' // 引入表情组件

// 新增自定义 Block Image Blot
const BlockEmbed = Quill.import('blots/block/embed')
class BlockImage extends BlockEmbed {
  static create(value) {
    const node = super.create()
    const img = document.createElement('img')
    img.setAttribute('src', value)
    node.appendChild(img)
    return node
  }
}
BlockImage.blotName = 'block-image'
BlockImage.tagName = 'div'
BlockImage.className = 'custom-image-wrapper'

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  height: {
    type: [String, Number],
    default: '400px'
  }
})
const ColorStyle = Quill.import('attributors/style/color')
const BackgroundStyle = Quill.import('attributors/style/background')
Quill.register(ColorStyle, true)
Quill.register(BackgroundStyle, true)
const emit = defineEmits(['update:modelValue'])
const editorHeight = ref(props.height)
const editorEl = ref(null)
let quill = null


// 初始化编辑器
onMounted(() => {
  // 注册自定义 blot
  Quill.register(BlockImage)

  quill = new Quill(editorEl.value, {
    theme: 'snow',
    suppressMutationObserver: true,  // 保留原有配置
    bounds: editorEl.value,         // 新增边界限制
    modules: {
      toolbar: {
        container: [
          ['bold', 'italic', 'underline'],
          [{ color: [] }, { background: [] }], // 添加背景色选择器
          ['image'],
          ['clean']
        ],
        handlers: {
          color: function (value) {
            this.quill.format('color', value)
          },
          background: function (value) {  // 新增背景色处理
            this.quill.format('background', value)
          },
        }
      }
    }
  })

  // 处理文本变化
  quill.on('text-change', () => {
    const html = quill.root.innerHTML
    emit('update:modelValue', DOMPurify.sanitize(html)) // XSS过滤
  })

  // 自定义图片上传
  quill.getModule('toolbar').addHandler('image', () => {
    const input = document.createElement('input')
    input.type = 'file'
    input.accept = 'image/*'

    input.onchange = async () => {
      const file = input.files[0]
      if (!file) return

      try {
        // 新增范围获取和安全检查
        const range = quill.getSelection()
        if (!range) {
          throw new Error('编辑器未获得焦点，请先点击编辑器区域')
        }


        // 上传图片
        const url = await uploadImage(file)

        // 替换占位为真实图片
        quill.deleteText(range.index, 1)
        // 修改为使用自定义 blot
        quill.insertEmbed(range.index, 'block-image', url)

        // 新增光标定位逻辑
        setTimeout(() => {
          quill.setSelection(range.index + 1, 0, 'silent') // 将光标定位到图片后
        }, 10)

      } catch (err) {
        // 新增错误提示
        console.error('图片上传失败:', err)
        quill.deleteText(range.index, 1)
        quill.insertText(range.index, `[上传失败: ${err.message}]`, { color: 'red' })
      }
    }

    input.click()
  })
})

// 图片上传方法
const uploadImage = async (file) => {
  const formData = new FormData()
  formData.append('file', file)

  const response = await service.post('/posts/temp-upload', formData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    },
  })

  console.log(response.message);

  return response.message // 从message字段获取URL


}

// 内容同步
watch(() => props.modelValue, (newVal) => {
  if (newVal !== quill.root.innerHTML) {
    quill.root.innerHTML = newVal
  }
})

const insertText = (text) => {
  // 确保编辑器容器获得焦点
  const editorContainer = document.querySelector('.editor-container')
  editorContainer?.focus()

  // 使用微任务确保焦点生效
  nextTick(() => {
    // 强制获取有效选区
    quill.focus()  // 新增：强制激活编辑器焦点
    const range = quill.getSelection() ?? { index: quill.getLength() }
    
    // 新增：保存当前滚动位置
    const scrollTop = quill.scroll.domNode.scrollTop
    
    // 修改插入逻辑
    quill.insertText(range.index, text, 'user')
    const newPosition = range.index + text.length
    
    // 使用定时器确保选区更新
    setTimeout(() => {
      quill.setSelection(newPosition, 0, 'user')
      quill.scroll.domNode.scrollTop = scrollTop
      quill.focus()
    }, 10)
  })
}

// 暴露格式化插入方法
defineExpose({
  quill,
  insertText  // 新增暴露方法
})
</script>

<style scoped>
@import '@/assets/css/editor.scss'
</style>
